#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string.h>
#include <netinet/in.h>//bind
#include <arpa/inet.h>//bind
using namespace std;

class UdpClient
{
public:
    UdpClient(string ip, uint16_t port)
    :_sockfd(-1)
    ,_ip(ip)
    ,_port(port)
    {}
    bool InitClient()
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(_sockfd < 0){
            cerr<< "socket error" << endl;
            return false;//创建失败
        }
        //client无需显示的bind, client->server
        //client -> connect!
        struct sockaddr_in server;
        memset(&server, 0, sizeof(server));
        server.sin_family = AF_INET;
        server.sin_port = htons(_port);
        //该函数做两件事情
        // 1. 将点分十进制的字符串风格的IP，转化成为4字节IP
        // 2. 将4字节由主机序列转化成为网络序列
        server.sin_addr.s_addr = inet_addr(_ip.c_str());
        if (connect(_sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
        {
            std::cout << "connect server failed !" << std::endl;
            return false;
        }
        std::cout << "connect success!" << std::endl;
    }
    void Start()
    {
        while(1)
        {
            std::cout << "Please Enter# ";
            char buffer[1024];
            fgets(buffer, sizeof(buffer)-1, stdin);

            write(_sockfd, buffer, strlen(buffer));

            ssize_t s = read(_sockfd, buffer, sizeof(buffer)-1);
            
            buffer[s] = '\0';//当作字符串读取

            cout << "server echo# " << buffer << endl;

        }
    }
private:
    int _sockfd;
    string _ip;
    uint16_t _port;
};
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        cout<<"Usage: \n\t"<< argv[0] <<" goal_IP" << " goal_port" << endl;
        return 1;
    }
    string ip = argv[1];
    uint16_t port = atoi(argv[2]);
    UdpClient* clt = new UdpClient(ip, port);
    clt->InitClient();
    clt->Start();

    return 0;
}